//
//  DownloadHelper.m
//  mcf
//
//  Created by yuike6 yuike6 on 12-2-8.
//  Copyright (c) 2012年 yuike. All rights reserved.
//

#import "DownloadHelper.h"
#import "header.h"


@implementation DownloadHelper
//@synthesize response = response_;
//@synthesize urlconnection = urlconnection_;

@synthesize data = data_;
//@synthesize urlString = urlString_;

@synthesize delegate = delegate_;
@synthesize isDownloading = isDownloading_;

@synthesize downloaderPool = downloaderPool_;
@synthesize downloaderTask = downloaderTask_;

@synthesize isCanceling;
@synthesize callBackLocak = callBackLocak_;

-(void) dealloc
{
//    YRelease(response_);
    
    
//    YRelease(urlconnection_);
//    YRelease(urlString_);
        
    [self.callBackLocak lock];
    [self.callBackLocak unlock];
    [self.downloaderTask cancelDownloader];    
    [self.downloaderTask stop];
    
    YRelease(downloaderTask_);
    YRelease(downloaderPool_);
    YRelease(data_);
    
    YRelease(callBackLocak_);
    [super dealloc];
}
/*

- (void) start
{
	self.isDownloading = NO;
	
	if (!self.urlString)
	{
		NSString *reason = [NSString stringWithFormat:@"Could not create URL from string %@", self.urlString];
		DELEGATE_CALLBACK(dataDownloadFailed:, reason);
		return;
	}
	
	NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:self.urlString];
	if (!theRequest)
	{
		NSString *reason = [NSString stringWithFormat:@"Could not create URL request from string %@", self.urlString];
		DELEGATE_CALLBACK(dataDownloadFailed:, reason);
		return;
	}
	
	self.urlconnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
	if (!self.urlconnection)
	{
		NSString *reason = [NSString stringWithFormat:@"URL connection failed for string %@", self.urlString];
		DELEGATE_CALLBACK(dataDownloadFailed:, reason);
		return;
	}
	
	self.isDownloading = YES;
	
	self.response = nil;
	
	[self.urlconnection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

- (void) cleanup
{
	self.data = nil;
	self.response = nil;
    
	self.urlconnection = nil;
	self.urlString = nil;
    
	self.isDownloading = NO;
}



- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse
{
	// store the response information
	self.response = aResponse;
	
    [self.data setNeedRecvDataLenght:[self.response expectedContentLength]];
	// Check for bad connection
	if ([aResponse expectedContentLength] < 0)
	{
		NSString *reason = [NSString stringWithFormat:@"Invalid URL [%@]", self.urlString];
		DELEGATE_CALLBACK(dataDownloadFailed:, reason);
		[connection cancel];
		[self cleanup];
		return;
	}
	
	if ([aResponse suggestedFilename])
		DELEGATE_CALLBACK(didReceiveFilename:, [aResponse suggestedFilename]);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
    if(!self.data)
    {
        self.data = [[[DownloadRecvDataMemory alloc] init] autorelease];
    }
    
	[self.data AppendData:theData];
	if (self.response)
	{
		float expectedLength = [self.response expectedContentLength];
		float currentLength = self.data.length;
		float percent = currentLength / expectedLength;
		DELEGATE_CALLBACK(dataDownloadAtPercent:, NUMBER(percent));
	}
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
	self.response = nil;	
	if (self.delegate)
	{
		NSData *theData = [self.data data] ;
		DELEGATE_CALLBACK(didReceiveDataFinish:, theData);
	}
	[self.urlconnection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
	[self cleanup];
}



- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
	self.isDownloading = NO;
	DebugLog(@"Error: Failed connection, %@", [error localizedDescription]);
	DELEGATE_CALLBACK(dataDownloadFailed:, @"Failed Connection");
	[self cleanup];
}*/


- (id) init
{
    self = [super init];
    if (self) {
        self.isCanceling = NO;
        if (!self.callBackLocak) {
            NSLock * lock__ = [[NSLock alloc] init];            
            self.callBackLocak = lock__;
            YRelease(lock__);
        }
    }
    return self;
}
- (void) downloadUrl:(NSString *) aURLString
{
//	if (self.isDownloading)
//	{
//		DebugLog(@"Error: Cannot start new download until current download finishes");
//		DELEGATE_CALLBACK(dataDownloadFailed:, @"some download task is running");
//		return;
//	}
//	
//	self.urlString = [NSURL URLWithString:aURLString];
//	[self start];
    
    if ([NSString isNilOrEmpty:aURLString]) {
        return;
    }
    
    [self download:[NSURL URLWithString:aURLString]];
}

- (void) download:(NSURL *) url
{    
    if (!url) 
    {
        return;
    }
    
    if ([url isFileURL]) 
    {
        return;
    }
    
    if (!self.downloaderPool) 
    {
        YTaskPool * pool_ = [[YTaskPool alloc] init];
        [pool_ setMaxConcurrentTaskCount:1];
        
        self.downloaderPool = pool_;
        YRelease(pool_);
    }
    
    [self cancel];
    [self.downloaderTask stop];
    
    DownloaderTask * task_ = [[DownloaderTask alloc] init];
    [task_ download:url];
    [task_ setRecvData:self.data];
    [task_ setDelegate:self];
    self.downloaderTask = task_;
    YRelease(task_);
    self.isCanceling = NO;
    [self.downloaderPool addTask:self.downloaderTask];
}

- (void) cancel
{
    [[self downloaderTask] cancelDownloader];
    self.isCanceling = YES;    
}

- (void) didTaskReceiveDataFinish: (NSData *) theData
{
    [self.callBackLocak lock];
    
    if (self.isCanceling) {
        [self.callBackLocak unlock];
        return;
    }
    DELEGATE_CALLBACK(didReceiveDataFinish:, theData);
    [self.callBackLocak unlock];
}

- (void) didTaskReceiveFilename: (NSString *) aName
{
    [self.callBackLocak lock];
    if (self.isCanceling) {
        [self.callBackLocak unlock];
        return;
    }
    DELEGATE_CALLBACK(didReceiveFilename:, aName);
    [self.callBackLocak unlock];
}

- (void) taskDataDownloadFailed: (NSString *) reason
{
    [self.callBackLocak lock];
    if (self.isCanceling) {
        [self.callBackLocak unlock];
        return;
    }
    DELEGATE_CALLBACK(dataDownloadFailed:, reason);  
    [self.callBackLocak unlock];
}

- (void) taskDataDownloadAtPercent: (NSNumber *) aPercent
{
    [self.callBackLocak lock];
    if (self.isCanceling) 
    {
        [self.callBackLocak unlock];
        return;
    }
    DELEGATE_CALLBACK(dataDownloadAtPercent:, aPercent);
    [self.callBackLocak unlock];
}

@end
